Enterprise Objects Framework Release 1.1 Copyright ã1995 by NeXT Computer, Inc.  All Rights Reserved.

EOAdaptorChannel

Inherits From:	NSObject

Declared In:	eoaccess/EOAdaptorChannel.h

Class Description

An EOAdaptorChannel represents an independent communication channel to the database server its EOAdaptor is connected to. You use an adaptor channel to manipulate rows (records) by selecting, fetching, inserting, deleting, and updating them. An adaptor channel also gives you access to some of the metadata on the server, such as what tables exist and what their basic attributes and relationships are.

All of an adaptor channel's operations take place within the context of transactions controlled or tracked by its EOAdaptorContext. An adaptor context may manage several channels (though not all can), but a channel is associated with only one context.

Accessing the Database

An adaptor channel operates on database rows in the form of NSDictionary objects. The keys of the dictionary represent the names of attributes (columns), the values for those keys are the values for the attributes. It's important to note that the table and column names in the database server are not the same as the entity and attribute names that the Enterprise Objects Framework uses (though an application can set them to be identical). It's also important to distinguish between a dictionary key that identifies a property of a row and that row's primary key, which is a subset of the dictionary's key-value pairs that uniquely identifies a row in the server.

Once you've set up a suite of adaptor objects and begun a transaction, you can have the adaptor channel operate on the data in the server. To insert a new row for a particular entity, for example, you create a dictionary object containing all the key-value pairs for the entity's properties, and send the channel an insertRow:forEntity: message.

The other three operationsÐdelete, update, and selectÐeach require an EOQualifier object to specify which rows to affect. An EOQualifier describes specific rows for a single entity based on the values of properties; for example, rows whose salary attribute is greater than 40,000. See the EOQualifier class specification for more information on creating qualifiers.

Fetching rows with an adaptor channel is a two-stage process. First, you select the rows with a selectAttributes:describedByQualifier:fetchOrder:lock: message. This establishes one or more result sets of records to be fetched. If the selection succeeds, you then send fetchAttributes:withZone: messages to retrieve individual rows until there are no more. This code template displays the highlights of the process:

EOAdaptorChannel *myChannel;   /* Assume this exists. */
EOEntity *employeeEntity;      /* Assume this exists. */
EOAttribute *salaryAttribute;
NSMutableArray *attributes;
EOQualifier *myQualifier;
NSMutableDictionary *theRow;
BOOL ok;

attributes = [NSMutableArray array];
salaryAttribute = [employeeEntity attributeNamed:@"salary"];
[attributes addObject:salaryAttribute];

myQualifier = [employeeEntity qualifier];

[[myChannel adaptorContext] beginTransaction];

ok = [myChannel selectAttributes:attributes
                describedByQualifier:myQualifier
                fetchOrder:nil lock:NO];

if (ok) {
    while (theRow = [myChannel fetchAttributes:attributes
                               withZone:NULL]) {
        /* Process theRow. */
    }
}

[[myChannel adaptorContext] commitTransaction];

To perform a fetch you need to specify the attributes you're interested in, and you need a qualifier to select the rows. You can ask the EOEntity object that represents a table for any of its named attributes; the excerpt above is using the attribute named ªsalaryº. You can get a basic qualifier for an entity, which results in a selectAttributes:... message selecting all records for that entity, or build a more restrictive qualifier, for example, one that only selects employees whose salary is above 4000. selectAttributes:describedByQualifier:fetchOrder:lock: then selects the records in preparation for fetching (see the description of this method for information on the fetch order and lock parameters). Once you've selected a set of records, you use a loop to fetch each one individually with fetchAttributes:withZone:.

Getting Basic Schema Information

You can use the adaptor-level objects without loading an EOModel file by having the adaptor channel read a minimal model from the database server's system dictionary. To build such a model you use the ªdescribe and readº methods:

describeTableNames
describeModelwithTableNames:

describeTableNames reads and returns an array of table names from the database. describeModelWithTableNames: constructs a default model out of the database's meta data.  It also puts the adaptor name and connection dictionary in the new model.

Notifying the Adaptor Channel's Delegate

All of the row-manipulation methods notify the adaptor channel's delegate before and after performing their operations. The delegate need only implement a message to receive it. The delegate may respond to a ªbeforeº message by allowing the operation, rejecting it, or overriding it. The return type of each of the ªbeforeº messages is EODelegateResponse, and an adaptor channel interprets the return value of a delegate message as follows:

Return Value	Interpretation

EODelegateRejects	Abort the requested operation and return a failure result.

EODelegateApproves	Continue the requested operation and return an appropriate result

EODelegateOverrides	Do nothing, but return a success result.

When a delegate overrides an operation, it's responsible for ensuring that the result of that operation is achieved. For example, if the delegate returns EODelegateOverrides from an adaptorChannel:willSelectAttributes:describedByQualifier:fetchOrder:lock: message, it must make sure that the appropriate rows are in fact selected.

Sending SQL Statements Directly to the Server

An EOAdaptorChannel allows you to send SQL directly to the database server with its evaluateExpression: method. This gives you access to database-specific features not made available by the adaptor channel itself, but can cause state changes on the server that aren't noted by objects in your application. If you cause state changes in evaluating SQL, you're responsible for notifying the appropriate objects of the changes; the classes of the Enterprise Objects Framework that are affected by evaluation of SQL typically describe the kinds of notifications they require.

If your adaptor doesn't have a model set, you can use describeResults to determine the attributes selected for a current fetch operation. Even if you perform the selection by sending raw SQL to the server, this method returns usable attributes that allow you to fetch rows.

Instance Variables

None declared in this class.

Method Types

Opening and closing a channel	- openChannel
- isOpen
- closeChannel

Modifying rows	- insertRow:forEntity:
- deleteRowsDescribedByQualifier:
- updateRow:describedByQualifier:

Fetching rows	+ dateForAttribute:year:month:day:hour:minute:
second:zone:
- selectAttributes:describedByQualifier:fetchOrder:lock:
- describeResults
- fetchAttributes:withZone:
- isFetchInProgress
- cancelFetch
- dictionaryWithObjects:forAttributes:zone:

Sending SQL to the server	- evaluateExpression:

Getting the adaptor context	- adaptorContext

Getting schema information	- describeModelWithTableNames:
- describeTableNames

Debugging	- setDebugEnabled:
- isDebugEnabled

Setting the channel's delegate	- setDelegate:
- delegate

Class Methods

dateForAttribute:year:month:day:hour:minute:second:zone:

+ (NSCalendarDate *)dateForAttribute:(EOAttribute *)attr year:(int)year month:(unsigned)month day:(unsigned)day hour:(unsigned)hour minute:(unsigned)minute second:(unsigned)second zone:(NSZone *)zone

EOAdaptorChannel subclasses can use this method to create a calendar date object to return in an adaptor row.

Instance Methods

adaptorContext

- (EOAdaptorContext *)adaptorContext

Returns the EOAdaptorChannel's EOAdaptorContext.

See also:  - adaptor (EOAdaptorContext)

cancelFetch

- (void)cancelFetch

Clears all result sets established by the last selectAttributes:describedByQualifier:fetchOrder:lock: message and terminates the current fetch, so that isFetchInProgress returns NO.

closeChannel

- (void)closeChannel

Closes the EOAdaptorChannel so that it can't perform operations with the server. Any fetch in progress is canceled. If the channel's adaptor context has outstanding transactions, however, the result depends on the server: Some database servers roll back all outstanding transactions but others do nothing.

See also:  - openChannel, - isOpen, - transactionNestingLevel (EOAdaptorContext)

delegate

- delegate

Returns the adaptor channel's delegate. A subclass of EOAdaptorChannel doesn't need to override this method.

deleteRowsDescribedByQualifier:

- (BOOL)deleteRowsDescribedByQualifier:(EOQualifier *)aQualifier

Deletes the rows described by aQualifier. The adaptor channel's context must have a transaction in effect for this method to work. Returns YES on success, NO on failure. Some possible reasons for failure are:

·	No row described by aQualifier exists (so no rows are actually deleted).
·	The user logged in to the database doesn't have permission to delete.
·	The adaptor channel is in an invalid state (for example, fetching).
·	The adaptor context has no transaction in progress.

This method invokes the delegate methods adaptorChannel:willDeleteRowsDescribedByQualifier: and adaptorChannel:didDeleteRowsDescribedByQualifier:.

describeAttributesForEntity:

- (NSArray *)describeAttributesForEntity:(EOEntity *)anEntity

Returns the basic attributes for anEntity constructed from metadata in the database server. This method doesn't actually assign the attributes to anEntityÐyour application must do that explicitly.

Note:  This method is obsolete. Use describeModelWithTableNames: and describeTableNames, instead.

See also:  - addEntity: (EOEntity), - describeModelWithTableNames:, - describeTableNames

describeEntities

- (NSArray *)describeEntities

Returns an array of entities constructed from metadata in the database server; for example, from the catalog or system tables. These entities contain no attribute or relationship informationÐyour application must load that explicitly.

Note:  This method is obsolete. Use describeModelWithTableNames: and describeTableNames, instead.

See also:  - addEntity: (EOModel), - describeAttributesForEntity:, - describeRelationshipsForEntity:, - describeModelWithTableNames:, - describeTableNames

describeModelWithTableNames:

- (EOModel *)describeModelWithTableNames:(NSArray *)tableNames

 Constructs a default model out of the database's meta data.  It also puts the adaptor name and connection dictionary in the new model. This method is typically used in conjunction with describeTableNames.

See also:  - describeTableNames

describeRelationshipsForEntity:

- (NSArray *)describeRelationshipsForEntity:(EOEntity *)anEntity

Returns the basic relationships for anEntity constructed from metadata in the database server (if such data is available). This method doesn't actually assign the relationships to anEntityÐyour application must do that explicitly.

Note:  This method is obsolete. Use describeModelWithTableNames: and describeTableNames, instead.

See also:  - addRelationship: (EOEntity class), - describeModelWithTableNames:, - describeTableNames

describeTableNames

- (NSArray *)describeTableNames

Reads and returns an array of table names from the database.  This method in conjunction with describeModelWithTableNames: is used to build a default model.

See also:  - describeModelWithTableNames:

describeResults

- (NSArray *)describeResults

Returns an array object of EOAttributes describing the properties available in the current result set, as determined by selectAttributes:describedByQualifier:fetchOrder:lock: or a select statement evaluated by evaluateExpression:.

dictionaryWithObjects:forAttributes:zone:

- (NSMutableDictionary *)dictionaryWithObjects:(id *)objects forAttributes:(NSArray *)attributes zone:(NSZone *)zone

This method is used by AdaptorChannel subclasses to create dictionaries that can be returned from fetchAttributes:withZone:. Use of this method is optional; it was added because it enables performance optimizations.

See also:  - fetchAttributes:withZone:

evaluateExpression:

- (BOOL)evaluateExpression:(NSString *)anExpression

Sends anExpression to the database server for evaluation. Returns YES if no error occurs, NO if any error occurs. An EOAdaptorChannel uses this method to perform all of its database operations.

Evaluation of an arbitrary expression may result in any number of changes in state on the server. Adaptors must at least track whether the evaluation of an expression results in a select operation being performed, thereby putting the adaptor in fetch mode. See the EODatabaseChannel class specification for special considerations in using this method with an EODatabaseChannel's adaptor channel.

This method invokes the delegate methods adaptorChannel:willEvaluateExpression: and adaptorChannel:didEvaluateExpression:.

See also:  - isFetchInProgress

fetchAttributes:withZone:

- (NSMutableDictionary *)fetchAttributes:(NSArray *)attributes withZone:(NSZone *)zone

Fetches the next row from the result set of the last selectAttributes:describedByQualifier:fetchOrder:lock: or evaluateExpression: message and returns values for the EOAttributes contained in attributes. When there are no more rows in the current result set, this method returns nil, and if there are more results sets this method invokes the delegate method adaptorChannelDidChangeResultSet:. When there are no more rows or result sets, this method returns nil, ends the fetch, and sends adaptorDidFinishFetching: to the delegate. isFetchInProgress returns YES until the fetch is cancelled or until this method exhausts all result sets and returns nil.

In addition to the delegate methods mentioned above, this method may also invoke the delegate methods adaptorChannel:willFetchAttributes:withZone: and adaptorChannel:didFetchAttributes:withZone:.

See also:  - cancelFetch

insertRow:forEntity:

- (BOOL)insertRow:(NSDictionary *)aRow forEntity:(EOEntity *)anEntity

Inserts the values of aRow into the table in the database that corresponds to anEntity. aRow is an NSDictionary whose keys are attribute names and whose values are the values to insert. The adaptor channel's context must have a transaction in effect for this method to work. Returns YES on success, NO on failure.

Some possible reasons for failure are:

·	The user logged in to the database doesn't have permission to insert a new row.
·	The adaptor channel is in an invalid state (for example, fetching).
·	The adaptor context has no transaction in progress.
·	The row fails to satisfy a constraint defined in the database server.

This method invokes the delegate methods adaptorChannel:willInsertRow:forEntity: and adaptorChannel:didInsertRow:forEntity:.

See also:  - deleteRowsDescribedByQualifier:, - selectAttributes:describedByQualfier:fetchOrder:lock:

isDebugEnabled

- (BOOL)isDebugEnabled

Returns YES if the adaptor channel logs evaluated SQL and other useful information to the console (or to the standard error stream), NO if not.

isFetchInProgress

- (BOOL)isFetchInProgress

Returns YES if the adaptor channel is fetching, NO otherwise. An adaptor channel is fetching if it's been sent a successful selectAttributes:describedByQualifier:fetchOrder:lock: message, or if an expression sent through evaluateExpression: resulted in a select operation being performed. An adaptor channel stops fetching when there are no more records to fetch or when it's sent a cancelFetch message.

See also:  - fetchAttributes:WithZone:

isOpen

- (BOOL)isOpen

Returns YES if the channel has been opened with openChannel, NO if not.

See also:  - closeChannel

openChannel

- (BOOL)openChannel

Puts the channel and both its context and adaptor into a state where they are ready to perform database operations. Returns YES on success, NO on failure or if the channel is already open.

See also:  - closeChannel, - isOpen, - hasValidConnectionDictionary (EOAdaptor)

readTypeForAttribute:

- (BOOL)readTypeForAttribute:(EOAttribute *)anAttribute

Loads external type information from the database server into anAttribute. Returns YES on success, NO on failure.

Attributes read with the describeAttributesForEntity: methods already have their type information set; you only need to use this method to read type information for a manually created attribute, or for an attribute whose type in the database may have changed.

readTypesForEntity:

- (BOOL)readTypesForEntity:(EOEntity *)anEntity

Loads external type information from the database server into all nonflattened attributes (not relationships) of anEntity. Returns YES on success, NO on failure.

Entities read with the describeEntities methods already have their type information set; you only need to use this method to read type information for a manually created entity, or for an entity whose attribute types in the database may have changed.

See also:  - describeAttributesForEntity:, - isFlattened (EOAttribute)

selectAttributes:describedByQualifier:fetchOrder:lock:

- (BOOL)selectAttributes:(NSArray *)attributes
describedByQualifier:(EOQualifier *)aQualifier
fetchOrder:(NSArray *)fetchOrder
lock:(BOOL)flag

Selects the EOAttributes in attributes for rows matching aQualifier. The selected rows compose one or more result sets, each row of which will be returned by subsequent fetchAttributes:withZone: messages according to fetchOrder (an array of EOAttributeOrdering objects). If fetchOrder is nil, rows aren't sorted as they're fetched. If flag is YES and the adaptor supports locking, the rows are locked so that no other user can modify them. The adaptor channel's context must have a transaction in effect for this method to work. Returns YES on success, NO on failure.

Some possible reasons for failure are:

·	The adaptor channel is in an invalid state (for example, fetching).
·	The adaptor context has no transaction in progress.
·	Locking was requested but the adaptor doesn't support it.

This method invokes the delegate methods adaptorChannel:willSelectAttributes:describedByQualifier:fetchOrder:lock: and adaptorChannel:didSelectAttributes:describedByQualifier:fetchOrder:lock:.

See also:  - isFetchInProgress, - cancelFetch

setDebugEnabled:

- (void)setDebugEnabled:(BOOL)flag

Sets according to flag whether the adaptor channel logs evaluated SQL and other useful debugging information to the console (or to the standard error stream). The information provided may vary from adaptor to adaptor and may change from release to release.

setDelegate:

- (void)setDelegate:anObject

Sets the adaptor channel's delegate to anObject and retains it. A subclass of EOAdaptorChannel doesn't need to override this method.

updateRow:describedByQualifier:

- (BOOL)updateRow:(NSDictionary *)newValues describedByQualifier:(EOQualifier *)aQualifier

Updates the row described by aQualifier by changing its values to match those in newValues. newValues is an NSDictionary whose keys are attribute names and whose values are the new values for those attributes (the dictionary need only contain entries for the attributes being changed). The adaptor channel's context must have a transaction in effect for this method to work. Returns YES on success, NO on failure. Some possible reasons for failure are:

·	No row described by aQualifier exists.
·	aQualifier describes more than one row.
·	The user logged in to the database doesn't have permission to update.
·	The adaptor channel is in an invalid state (for example, fetching).
·	The adaptor context has no transaction in progress.
·	The new values fail to satisfy a constraint defined in the database server.

This method invokes the delegate methods adaptorChannel:willUpdateRow:describedByQualifier: and adaptorChannel:didUpdateRow:describedByQualifier:.

See also:  - isFetchInProgress, - beginTransaction (EOAdaptorContext)

Methods Implemented by the Delegate

adaptorChannelDidChangeResultSet:

- (void)adaptorChannelDidChangeResultSet:channel

Invoked from fetchAttributes:withZone: to tell the delegate that fetching will start for the next result set when a select operation resulted in multiple result sets. This method is invoked just before a fetchAttributes:withZone: returns nil when there are still result sets left to fetch.

adaptorChannel:didDeleteRowsDescribedByQualifier:

- (void)adaptorChannel:channel didDeleteRowsDescribedByQualifier:(EOQualifier *)aQualifier

Invoked from deleteRowsDescribedByQualifier: to tell the delegate that some rows have been deleted. The delegate may take whatever action it needs based on this information.

adaptorChannel:didEvaluateExpression:

- (void)adaptorChannel:channel didEvaluateExpression:(NSString *)anExpression

Invoked from evaluateExpression: to tell the delegate that a query language expression has been evaluated by the database server. Note that nearly every method that communicates with a database does so by using evaluateExpression:. The delegate may take whatever action it needs based on this information. Note that the adaptor channel can determine whether anExpression resulted in a select operation being performed.

adaptorChannel:didFetchAttributes:withZone:

- (NSMutableDictionary *)adaptorChannel:channel
didFetchAttributes:(NSMutableDictionary *)attributes
withZone:(NSZone *)zone

Invoked from fetchAttributes:withZone: to tell the delegate that a single row has been fetched. The delegate may return a substitute dictionary that will be used instead of attributes, or return nil to cause fetchAttributes:withZone: to fail and return nil. Returning nil doesn't cancel the fetch, however.

See also:  - cancelFetch

adaptorChannelDidFinishFetching:

- (void)adaptorChannelDidFinishFetching:channel

Invoked from fetchAttributes:withZone: to tell the delegate that fetching is finished for the current select operation. This method is invoked when a fetch ends in fetchAttributes:withZone: because there are no more result sets.

adaptorChannel:didInsertRow:forEntity:

- (void)adaptorChannel:channel
didInsertRow:(NSDictionary *)aRow
forEntity:(EOEntity *)anEntity

Invoked from insertRow:forEntity: to tell the delegate that a row has been inserted. The delegate may use this information to update records, redisplay onscreen information, or take whatever other action it needs.

adaptorChannel:didSelectAttributes:describedByQualifier:
fetchOrder:lock:

- (void)adaptorChannel:channel
didSelectAttributes:(NSArray *)attributes
describedByQualifier:(EOQualifier *)aQualifier
fetchOrder:(NSArray *)fetchOrder
lock:(BOOL)flag

Invoked from selectAttributes:describedByQualifier:fetchOrder:lock: to tell the delegate that some rows have been selected. The delegate may take whatever action it needs based on this information.

adaptorChannel:didUpdateRow:describedByQualifier:

- (void)adaptorChannel:channel
didUpdateRow:(NSDictionary *)newValues
describedByQualifier:(EOQualifier *)aQualifier

Invoked from updateRow:describedByQualifier: to tell the delegate that a row has been updated. newValues are the values written to the row described by aQualifier. The delegate may take whatever action it needs based on this information.

adaptorChannel:willDeleteRowsDescribedByQualifier:

- (EODelegateResponse)adaptorChannel:channel willDeleteRowsDescribedByQualifier:(EOQualifier *)aQualifier

Invoked from deleteRowsDescribedByQualifier: to tell the delegate that a row is being deleted. The delegate can modify aQualifier to affect the result of the delete operation. See ªNotifying the Adaptor Channel's Delegateº in the class description for an explanation of the possible return values.

adaptorChannel:willEvaluateExpression:

- (EODelegateResponse)adaptorChannel:channel willEvaluateExpression:(NSMutableString *)anExpression

Invoked from evaluateExpression: to tell the delegate that anExpression is about to be sent to the database server. Note that nearly every method that communicates with a database does so by using evaluateExpression:. The delegate may modify anExpression to affect the result. See ªNotifying the Adaptor Channel's Delegateº in the class description for an explanation of the possible return values.

adaptorChannel:willFetchAttributes:withZone:

- (NSMutableDictionary *)adaptorChannel:channel
willFetchAttributes:(NSArray *)attributes withZone:(NSZone *)zone

Invoked from fetchAttributes:withZone: to tell the delegate that a single row will be fetched. If the delegate returns a non-nil value, that value will be treated as a dictionary resulting from a fetch operation; the adaptor channel doesn't perform a fetch, and fetchAttributes:withZone: returns YES. The delegate must ensure that the server skips the current row so that the next fetch message doesn't simply get that same row.

If the delegate returns nil the adaptor channel performs the fetch itself.

adaptorChannel:willInsertRow:forEntity:

- (EODelegateResponse)adaptorChannel:channel
willInsertRow:(NSMutableDictionary *)aRow
forEntity:(EOEntity *)anEntity

Invoked from insertRow:forEntity: to tell the delegate that a row is being inserted. The delegate can change the values for attribute names in aRow, or add or delete attribute-value pairs. See ªNotifying the Adaptor Channel's Delegateº in the class description for an explanation of the possible return values.

adaptorChannel:willSelectAttributes:describedByQualifier:
fetchOrder:lock:

- (EODelegateResponse)adaptorChannel:channel
willSelectAttributes:(NSMutableArray *)attributes
describedByQualifier:(EOQualifier *)aQualifier
fetchOrder:(NSArray *)fetchOrder
lock:(BOOL)flag

Invoked from selectAttributes:describedByQualifier:fetchOrder:lock: to tell the delegate that a select operation is being performed. The delegate can modify attributes to affect the select operation, but shouldn't modify aQualifier. See ªNotifying the Adaptor Channel's Delegateº in the class description for an explanation of the possible return values.

adaptorChannel:willUpdateRow:describedByQualifier:

- (EODelegateResponse)adaptorChannel:channel
willUpdateRow:(NSMutableDictionary *)newValues
describedByQualifier:(EOQualifier *)aQualifier

Invoked from updateRow:describedByQualifier: to tell the delegate that the row described by aQualifier will be updated. The delegate can change the values for particular attribute names in newValues, add or delete entire entries, and can modify aQualifier to affect the update operation. See ªNotifying the Adaptor Channel's Delegateº in the class description for an explanation of the possible return values.